package com.changzhi.controller;

import com.alibaba.fastjson.JSON;
import com.changzhi.common.annotation.Verify;
import com.changzhi.common.util.Result;
import com.changzhi.ldyl.model.dto.CarnivalBeastDto;
import com.changzhi.ldyl.model.dto.CarnivalBoxDto;
import com.changzhi.ldyl.model.dto.CarnivalCardDto;
import com.changzhi.ldyl.model.dto.LanternDto;
import com.changzhi.service.CarnivalService;
import com.changzhi.service.LanternService;
import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description:
 * @author: 小落
 * @date: 2021年01月14日
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("carnival")
public class CarnivalController {

	@Autowired
	private CarnivalService carnivalService;
	@Autowired
	private LanternService lanternService;

	//创建一个限速器，每1秒，产生100个令牌
	//public final static RateLimiter limit = RateLimiter.create(200);
	public final static Map<String, RateLimiter> userLimitMap = new ConcurrentHashMap<>();


	/********************************** 宝箱 **************************************/
	@Verify(login = false)
	@PostMapping("showBox")
	public Result showBox(@RequestBody @Validated CarnivalBoxDto carnivalBoxDto){
		//long start = System.currentTimeMillis();
		/*boolean success = limit.tryAcquire();
		if(!success){
			Result.error("请稍候重试");
		}*/
		Object data = carnivalService.showBox(carnivalBoxDto);
		//log.info("methodName:cardList,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify
	@PostMapping("openBox")
	public Result openBox(@RequestBody @Validated CarnivalBoxDto carnivalBoxDto){
		String userId = carnivalBoxDto.getUserId();
		RateLimiter rateLimiter = userLimitMap.get(userId);
		if(rateLimiter == null){
			rateLimiter = RateLimiter.create(50);
			userLimitMap.put(userId, rateLimiter);
		}
		if(!rateLimiter.tryAcquire()){
			return Result.error("请稍候重试");
		}

		long start = System.currentTimeMillis();
		Object data = carnivalService.openBox(carnivalBoxDto);
		log.info("methodName:openBox,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}


	@Verify
	@PostMapping("getPush")
	public Result getPush(@RequestBody @Validated CarnivalBoxDto carnivalBoxDto){
		/*boolean success = limit.tryAcquire();
		if(!success){
			Result.error("请稍候重试");
		}*/
		long start = System.currentTimeMillis();
		Map<String, Object> data = carnivalService.getPush(carnivalBoxDto);
		log.info("methodName:getPush,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	/********************************** 拼图汇 **************************************/
	@Verify
	@PostMapping("cardList")
	public Result cardList(@RequestBody @Validated CarnivalCardDto carnivalCardDto){
		long start = System.currentTimeMillis();
		Object data = carnivalService.cardList(carnivalCardDto);
		log.info("methodName:cardList,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify
	@PostMapping("cardRankings")
	public Result cardRankings(@RequestBody @Validated CarnivalCardDto carnivalCardDto){
		long start = System.currentTimeMillis();
		Object data = carnivalService.cardRankings(carnivalCardDto);
		log.info("methodName:cardRankings,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify
	@PostMapping("receiveAward")
	public Result receiveAward(@RequestBody @Validated CarnivalCardDto carnivalCardDto){
		long start = System.currentTimeMillis();
		Object data = carnivalService.receiveAward(carnivalCardDto);
		log.info("methodName:receiveAward,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	/********************************** 年兽作战 **************************************/
	@Verify(login = false)
	@PostMapping("harmRankings")
	public Result harmRankings(@RequestBody @Validated CarnivalBeastDto carnivalBeastDto){
		//long start = System.currentTimeMillis();
		Object data = carnivalService.harmRankings(carnivalBeastDto);
		//log.info("methodName:harmRankings,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify(login = false)
	@PostMapping("realTimeRankings")
	public Result realTimeRankings(@RequestBody @Validated CarnivalBeastDto carnivalBeastDto){
		//long start = System.currentTimeMillis();
		Object data = carnivalService.realTimeRankings();
		//log.info("methodName:realTimeRankings,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify
	@PostMapping("specialPrize")
	public Result specialPrize(@RequestBody @Validated CarnivalCardDto carnivalCardDto){
		//long start = System.currentTimeMillis();
		Object data = carnivalService.specialPrize(carnivalCardDto);
		//log.info("methodName:specialPrize,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}


	/********************************** 守护恋语 **************************************/
	@Verify
	@PostMapping("loveInfo")
	public Result loveInfo(@RequestBody @Validated LanternDto lanternDto){
		long start = System.currentTimeMillis();
		Object data = lanternService.loveInfo(lanternDto);
		log.info("methodName:loveInfo,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify(login = false)
	@PostMapping("loveRankings")
	public Result loveRankings(@RequestBody @Validated LanternDto lanternDto){
		long start = System.currentTimeMillis();
		Object data = lanternService.loveRankings(lanternDto);
		log.info("methodName:loveRankings,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	@Verify
	@PostMapping("exchangeAward")
	public Result exchangeAward(@RequestBody @Validated LanternDto lanternDto){
		long start = System.currentTimeMillis();
		Object data = lanternService.exchangeAward(lanternDto);
		log.info("methodName:exchangeAward,耗时={}", System.currentTimeMillis() - start);
		return Result.success(data);
	}

	/********************************** 元宵节灯谜 **************************************/
	@Verify
	@PostMapping("lanternInfo")
	public Result lanternInfo(@RequestBody @Validated LanternDto lanternDto){
		Object data = lanternService.lanternInfo(lanternDto);
		return Result.success(data);
	}

	@Verify
	@PostMapping("getResult")
	public Result getResult(@RequestBody @Validated LanternDto lanternDto){
		log.info("methodName:getResult,lanternDto={}", JSON.toJSONString(lanternDto));
		Object data = lanternService.getResult(lanternDto);
		return Result.success(data);
	}

	@Verify
	@PostMapping("lanternRankings")
	public Result lanternRankings(@RequestBody @Validated LanternDto lanternDto){
		Object data = lanternService.lanternRankings(lanternDto);
		return Result.success(data);
	}
}
